/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is Forte for Java, Community Edition. The Initial
* Developer of the Original Code is Sun Microsystems, Inc. Portions
* Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.apisupport.beanbrowser;
import java.awt.event.ActionEvent;
import java.util.*;
import javax.swing.JMenuItem;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.tree.TreeNode;
import org.openide.TopManager;
import org.openide.awt.Actions;
import org.openide.awt.JInlineMenu;
import org.openide.explorer.view.Visualizer;
import org.openide.nodes.*;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.*;
public class NodeExploreAction extends NodeAction {
private static final long serialVersionUID =9138110746394596949L;
protected void performAction (Node[] nodes) {
// do nothing -- should never be called
}
protected boolean enable (Node[] nodes) {
return nodes.length == 1;
}
public String getName () {
return "Explore node...";
}
protected String iconResource () {
return "/org/netbeans/modules/apisupport/resources/NodeExploreIcon.gif";
}
public HelpCtx getHelpCtx () {
return new HelpCtx ("org.netbeans.modules.apisupport.beanbrowser.nodeinfo");
}
public JMenuItem getMenuPresenter() {
if (anythingToDisplay ())
return new SpecialSubMenu (this, getModel (), false);
else
return new JInlineMenu (); // do not display at all
}
public JMenuItem getPopupPresenter() {
if (anythingToDisplay ())
return new SpecialSubMenu (this, getModel (), true);
else
return new JInlineMenu (); // do not display at all
}
private boolean anythingToDisplay () {
// test whether or not there will be anything to display in the submenu
// if false, whole item will just disappear
return true;
}
private static ActSubMenuModel model = null;
static ActSubMenuModel getModel () {
if (model == null)
model = new ActSubMenuModel ();
return model;
}
private Node[] getActivatedNodes0 () {
return getActivatedNodes ();
}
/** Special submenu which notifies model when it is added as a component.
*/
private static final class SpecialSubMenu extends Actions.SubMenu {
// private static final long serialVersionUID = ...;
private static final long serialVersionUID =-8517802693603421361L;
SpecialSubMenu (SystemAction action, Actions.SubMenuModel model, boolean popup) {
super (action, model, popup);
}
public void addNotify () {
NodeExploreAction.getModel ().addNotify ();
super.addNotify ();
}
// removeNotify not useful--might be called before action is invoked
}
/** Model to use for the submenu.
*/
private static final class ActSubMenuModel implements Actions.SubMenuModel {
/**
* @associates String
*/
private List displayNames;
/**
* @associates Explorer
*/
private List associatedInfo;
/**
* @associates ChangeListener
*/
private Set listeners = new HashSet (); // Set<ChangeListener>
public int getCount() {
return displayNames.size ();
}
public String getLabel (int index) {
return (String) displayNames.get (index);
}
public HelpCtx getHelpCtx (int index) {
return HelpCtx.DEFAULT_HELP; // could add something special here, or new HelpCtx (NodeExploreAction.class)
}
public void performActionAt (int index) {
Object info = associatedInfo.get (index);
Explorer e = (Explorer) info;
Node[] nodes = ((NodeExploreAction) SystemAction.get (NodeExploreAction.class)).getActivatedNodes0 ();
if (nodes.length != 1) throw new Error ();
Node n = nodes[0];
if (n instanceof Wrapper) n = ((Wrapper) n).getOriginal ();
TopManager.getDefault ().getNodeOperation ().explore (e.explore (n));
}
public synchronized void addChangeListener (ChangeListener l) {
listeners.add (l);
}
public synchronized void removeChangeListener (ChangeListener l) {
listeners.remove (l);
}
/** You may use this is you have attached other listeners to things that will affect displayNames, for example. */
private synchronized void fireStateChanged () {
if (listeners.size () == 0) return;
ChangeEvent ev = new ChangeEvent (this);
Iterator it = listeners.iterator ();
while (it.hasNext ())
((ChangeListener) it.next ()).stateChanged (ev);
}
void addNotify () {
displayNames = new ArrayList (5);
associatedInfo = new ArrayList (5);
displayNames.add ("Itself");
associatedInfo.add (new Explorer () {
public Node explore (Node n) {
return n;
}
});
displayNames.add ("Its clone");
associatedInfo.add (new Explorer () {
public Node explore (Node n) {
return n.cloneNode ();
}
});
displayNames.add ("Its parent");
associatedInfo.add (new Explorer () {
public Node explore (Node n) {
Node p = n.getParentNode ();
if (p != null) {
return p;
} else {
AbstractNode toret = new AbstractNode (Children.LEAF) {
public HelpCtx getHelpCtx () {
return new HelpCtx ("org.netbeans.modules.apisupport.beanbrowser.nodeinfo");
}
};
toret.setName ("<No Parent>");
toret.setIconBase ("/org/netbeans/modules/apisupport/resources/NodeExploreIcon");
return toret;
}
}
});
displayNames.add ("Its parent's clone");
associatedInfo.add (new Explorer () {
public Node explore (Node n) {
Node p = n.getParentNode ();
if (p != null) {
return p.cloneNode ();
} else {
AbstractNode toret = new AbstractNode (Children.LEAF) {
public HelpCtx getHelpCtx () {
return new HelpCtx ("org.netbeans.modules.apisupport.beanbrowser.nodeinfo");
}
};
toret.setName ("<No Parent>");
toret.setIconBase ("/org/netbeans/modules/apisupport/resources/NodeExploreIcon");
return toret;
}
}
});
displayNames.add ("Its visualizer");
associatedInfo.add (new Explorer () {
public Node explore (Node n) {
return new VisualizerNode (n);
}
});
displayNames.add ("Itself as a bean");
associatedInfo.add (new Explorer () {
public Node explore (Node n) {
return PropSetKids.makeObjectNode (n);
}
});
}
}
interface Explorer {
// Always the original node here:
Node explore (Node n);
}
private static class VisualizerNode extends AbstractNode {
VisualizerNode (Node n) {
this (Visualizer.findVisualizer (n));
}
VisualizerNode (TreeNode tn) {
super (new VisualizerChildren (tn));
setName ("Visualizer of " + tn);
// [PENDING] does not work for some reason:
setIconBase ("/org/netbeans/modules/apisupport/resources/NodeExploreIcon");
}
public HelpCtx getHelpCtx () {
return new HelpCtx ("org.netbeans.modules.apisupport.beanbrowser.nodeinfo");
}
}
private static final class VisualizerChildren extends Children.Keys {
private TreeNode tree;
public VisualizerChildren (TreeNode n) {
this.tree = n;
}
protected void addNotify () {
java.util.LinkedList list = new java.util.LinkedList ();
java.util.Enumeration en = tree.children ();
while (en.hasMoreElements ()) {
list.add (en.nextElement ());
}
setKeys (list);
}
protected void removeNotify () {
setKeys (java.util.Collections.EMPTY_SET);
}
protected Node[] createNodes (Object key) {
return new Node[] { new VisualizerNode ((TreeNode) key) };
}
}
}
/*
* Log
* 4 Gandalf-post-FCS1.2.1.0 3/28/00 Jesse Glick SVUIDs.
* 3 Gandalf 1.2 12/23/99 Jesse Glick "Itself as a Bean"
* exploration mode.
* 2 Gandalf 1.1 10/27/99 Jesse Glick Sun copyrights.
* 1 Gandalf 1.0 10/25/99 Jesse Glick
* $
*/